[llvm] a9f4d3f - [GlobalISel] Add G_VECTOR_COMPRESS support of computeKnownBits & computeNumSignBits (#223967)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 21 06:05:06 PDT 2026


Author: Vikash Gupta
Date: 2026-09-21T18:34:59+05:30
New Revision: a9f4d3ff18c554d29bbabc546f9a9df0376701e0

URL: https://github.com/llvm/llvm-project/commit/a9f4d3ff18c554d29bbabc546f9a9df0376701e0
DIFF: https://github.com/llvm/llvm-project/commit/a9f4d3ff18c554d29bbabc546f9a9df0376701e0.diff

LOG: [GlobalISel] Add G_VECTOR_COMPRESS support of computeKnownBits & computeNumSignBits (#223967)

Port the value tracking for ISD::VECTOR_COMPRESS to the GlobalISel
G_VECTOR_COMPRESS. Each result lane is either a lane of the source or
the passthrough operand, so:
  - KnownBits is the intersection of the source and passthrough and,
  - the number of sign bits is the minimum of the two.

Added: 
    llvm/test/CodeGen/AArch64/GlobalISel/knownbits-vector-compress.mir

Modified: 
    llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 4f3de265bf543..95984afe36d3b 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -1188,6 +1188,22 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
     }
     break;
   }
+  case TargetOpcode::G_VECTOR_COMPRESS: {
+    // Each result lane is either a lane of the source vector or the passthru,
+    // so the known bits are those shared by both.
+    Register Vec = MI.getOperand(1).getReg();
+    Register PassThru = MI.getOperand(3).getReg();
+    computeKnownBitsImpl(PassThru, Known, DemandedElts, Depth + 1);
+    // If we don't know any bits, early out.
+    if (Known.isUnknown())
+      break;
+    // Compression can move any source lane to any result position, so all
+    // source lanes are demanded.
+    APInt DemandedSrcElts = APInt::getAllOnes(DemandedElts.getBitWidth());
+    computeKnownBitsImpl(Vec, Known2, DemandedSrcElts, Depth + 1);
+    Known = Known.intersectWith(Known2);
+    break;
+  }
   case TargetOpcode::G_ABS: {
     Register SrcReg = MI.getOperand(1).getReg();
     computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1);
@@ -2796,6 +2812,22 @@ unsigned GISelValueTracking::computeNumSignBits(Register R,
     }
     break;
   }
+  case TargetOpcode::G_VECTOR_COMPRESS: {
+    // Each result lane is either a lane of the source vector or the passthru,
+    // so the number of sign bits is the minimum of the two.
+    Register Vec = MI.getOperand(1).getReg();
+    Register PassThru = MI.getOperand(3).getReg();
+    unsigned Tmp = computeNumSignBits(PassThru, DemandedElts, Depth + 1);
+    // If passthru contributes nothing, fall back to the KnownBits refinement.
+    if (Tmp == 1)
+      break;
+    // Compression can move any source lane to any result position, so all
+    // source lanes are demanded.
+    APInt DemandedSrcElts = APInt::getAllOnes(DemandedElts.getBitWidth());
+    unsigned Tmp2 = computeNumSignBits(Vec, DemandedSrcElts, Depth + 1);
+    FirstAnswer = std::min(Tmp, Tmp2);
+    break;
+  }
   case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
     GExtractVectorElement &Extract = cast<GExtractVectorElement>(MI);
     Register InVec = Extract.getVectorReg();

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-vector-compress.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-vector-compress.mir
new file mode 100644
index 0000000000000..88bbee44f0355
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-vector-compress.mir
@@ -0,0 +1,83 @@
+# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple=aarch64 -passes="print<gisel-value-tracking>" -filetype=null %s 2>&1 | FileCheck %s
+
+---
+# KnownBits: 0x00F0 and 0x0FF0 agree on the low/high zeros and bits 4..7, but
+# disagree on bits 8..11 -> those become unknown in the result.
+name:            CompressKnownIntersect
+body:             |
+  bb.0:
+  ; CHECK-LABEL: name: @CompressKnownIntersect
+  ; CHECK-NEXT: %0:_ KnownBits:00000000000000000000000011110000 SignBits:24 IsKnownNeverZero:1
+  ; CHECK-NEXT: %1:_ KnownBits:00000000000000000000000011110000 SignBits:24 IsKnownNeverZero:1
+  ; CHECK-NEXT: %2:_ KnownBits:00000000000000000000111111110000 SignBits:20 IsKnownNeverZero:1
+  ; CHECK-NEXT: %3:_ KnownBits:00000000000000000000111111110000 SignBits:20 IsKnownNeverZero:1
+  ; CHECK-NEXT: %4:_ KnownBits:? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %5:_ KnownBits:00000000000000000000????11110000 SignBits:20 IsKnownNeverZero:1
+    %0:_(s32) = G_CONSTANT i32 240
+    %1:_(<4 x s32>) = G_BUILD_VECTOR %0, %0, %0, %0
+    %2:_(s32) = G_CONSTANT i32 4080
+    %3:_(<4 x s32>) = G_BUILD_VECTOR %2, %2, %2, %2
+    %4:_(<4 x s1>) = G_IMPLICIT_DEF
+    %5:_(<4 x s32>) = G_VECTOR_COMPRESS %1, %4, %3
+...
+---
+# KnownBits: an unknown passthru forces the whole result to unknown, since any
+# result lane may come from the passthru.
+name:            CompressPassthruUnknown
+body:             |
+  bb.0:
+    liveins: $q0
+  ; CHECK-LABEL: name: @CompressPassthruUnknown
+  ; CHECK-NEXT: %0:_ KnownBits:00000000000000000000111111110000 SignBits:20 IsKnownNeverZero:1
+  ; CHECK-NEXT: %1:_ KnownBits:00000000000000000000111111110000 SignBits:20 IsKnownNeverZero:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %3:_ KnownBits:? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %4:_ KnownBits:???????????????????????????????? SignBits:1 IsKnownNeverZero:0
+    %0:_(s32) = G_CONSTANT i32 4080
+    %1:_(<4 x s32>) = G_BUILD_VECTOR %0, %0, %0, %0
+    %2:_(<4 x s32>) = COPY $q0
+    %3:_(<4 x s1>) = G_IMPLICIT_DEF
+    %4:_(<4 x s32>) = G_VECTOR_COMPRESS %1, %3, %2
+...
+---
+# NumSignBits: both sources are sign-extended from 8 bits (25 sign bits each), so
+# the result has min(25,25)=25 sign bits -- information the intersected KnownBits
+# alone cannot recover (the two unknown signs 
diff er).
+name:            CompressSignBits
+body:             |
+  bb.0:
+    liveins: $q0, $q1
+  ; CHECK-LABEL: name: @CompressSignBits
+  ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:25 IsKnownNeverZero:0
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %3:_ KnownBits:???????????????????????????????? SignBits:25 IsKnownNeverZero:0
+  ; CHECK-NEXT: %4:_ KnownBits:? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %5:_ KnownBits:???????????????????????????????? SignBits:25 IsKnownNeverZero:0
+    %0:_(<4 x s32>) = COPY $q0
+    %1:_(<4 x s32>) = G_SEXT_INREG %0, 8
+    %2:_(<4 x s32>) = COPY $q1
+    %3:_(<4 x s32>) = G_SEXT_INREG %2, 8
+    %4:_(<4 x s1>) = G_IMPLICIT_DEF
+    %5:_(<4 x s32>) = G_VECTOR_COMPRESS %1, %4, %3
+...
+---
+# Scalable-vector path: same intersection, per lane.
+name:            CompressScalable
+body:             |
+  bb.0:
+  ; CHECK-LABEL: name: @CompressScalable
+  ; CHECK-NEXT: %0:_ KnownBits:00000000000000000000000011110000 SignBits:24 IsKnownNeverZero:1
+  ; CHECK-NEXT: %1:_ KnownBits:00000000000000000000000011110000 SignBits:24 IsKnownNeverZero:1
+  ; CHECK-NEXT: %2:_ KnownBits:00000000000000000000111111110000 SignBits:20 IsKnownNeverZero:1
+  ; CHECK-NEXT: %3:_ KnownBits:00000000000000000000111111110000 SignBits:20 IsKnownNeverZero:1
+  ; CHECK-NEXT: %4:_ KnownBits:? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %5:_ KnownBits:00000000000000000000????11110000 SignBits:20 IsKnownNeverZero:1
+    %0:_(s32) = G_CONSTANT i32 240
+    %1:_(<vscale x 4 x s32>) = G_SPLAT_VECTOR %0
+    %2:_(s32) = G_CONSTANT i32 4080
+    %3:_(<vscale x 4 x s32>) = G_SPLAT_VECTOR %2
+    %4:_(<vscale x 4 x s1>) = G_IMPLICIT_DEF
+    %5:_(<vscale x 4 x s32>) = G_VECTOR_COMPRESS %1, %4, %3
+...


        


More information about the llvm-commits mailing list