[llvm] [GlobalISel] Add G_EXTRACT_VECTOR_ELT to computeNumSignBits (PR #218283)
Deepak Shirke via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 23 13:17:20 PDT 2026
https://github.com/deepakshirkem updated https://github.com/llvm/llvm-project/pull/218283
>From b1c35444100c352a008b1414d96b8a4a23b73d21 Mon Sep 17 00:00:00 2001
From: deepakshirkem <deepakshirke509 at gmail.com>
Date: Mon, 24 Aug 2026 01:20:42 +0530
Subject: [PATCH 1/2] [GlobalISel] Add G_EXTRACT_VECTOR_ELT to
computeNumSignBits
Port the SDAG EXTRACT_VECTOR_ELT computeNumSignBits handling to GlobalISel.
If the element index is known, demand only that element from the source
vector. If unknown, conservatively demand all elements.
---
.../CodeGen/GlobalISel/GISelValueTracking.cpp | 15 +++
.../GlobalISel/knownbits-extract-vector.mir | 105 ++++++++++++------
2 files changed, 83 insertions(+), 37 deletions(-)
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 0672cfffc6eac..1674c98f40ffa 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -2669,6 +2669,21 @@ unsigned GISelValueTracking::computeNumSignBits(Register R,
}
break;
}
+ case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
+ GExtractVectorElement &Extract = cast<GExtractVectorElement>(MI);
+ Register InVec = Extract.getVectorReg();
+ Register EltNo = Extract.getIndexReg();
+ LLT VecVT = MRI.getType(InVec);
+ if (VecVT.isScalableVector())
+ break;
+ unsigned NumSrcElts = VecVT.getNumElements();
+ auto ConstEltNo = getIConstantVRegVal(EltNo, MRI);
+ APInt DemandedSrcElts = APInt::getAllOnes(NumSrcElts);
+ if (ConstEltNo && ConstEltNo->ult(NumSrcElts))
+ DemandedSrcElts =
+ APInt::getOneBitSet(NumSrcElts, ConstEltNo->getZExtValue());
+ return computeNumSignBits(InVec, DemandedSrcElts, Depth + 1);
+ }
case TargetOpcode::G_EXTRACT_SUBVECTOR: {
// Offset the demanded elts by the subvector index.
Register SrcReg = MI.getOperand(1).getReg();
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-extract-vector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-extract-vector.mir
index 7ff593f18adc9..23084e288ac53 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-extract-vector.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-extract-vector.mir
@@ -6,11 +6,11 @@ name: all_knownbits_const_idx
body: |
bb.0:
; CHECK-LABEL: name: @all_knownbits_const_idx
- ; CHECK-NEXT: %0:_ KnownBits:00000011 SignBits:6
- ; CHECK-NEXT: %1:_ KnownBits:00001010 SignBits:4
- ; CHECK-NEXT: %2:_ KnownBits:0000?01? SignBits:4
- ; CHECK-NEXT: %idx:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000001 SignBits:63
- ; CHECK-NEXT: %4:_ KnownBits:00001010 SignBits:4
+ ; CHECK-NEXT: %0:_ KnownBits:00000011 SignBits:6 IsKnownNeverZero:1
+ ; CHECK-NEXT: %1:_ KnownBits:00001010 SignBits:4 IsKnownNeverZero:1
+ ; CHECK-NEXT: %2:_ KnownBits:0000?01? SignBits:4 IsKnownNeverZero:1
+ ; CHECK-NEXT: %idx:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000001 SignBits:63 IsKnownNeverZero:1
+ ; CHECK-NEXT: %4:_ KnownBits:00001010 SignBits:4 IsKnownNeverZero:1
%0:_(i8) = G_CONSTANT i8 3
%1:_(i8) = G_CONSTANT i8 10
%2:_(<2 x i8>) = G_BUILD_VECTOR %0, %1
@@ -22,11 +22,11 @@ name: all_knownbits
body: |
bb.0:
; CHECK-LABEL: name: @all_knownbits
- ; CHECK-NEXT: %0:_ KnownBits:00000011 SignBits:6
- ; CHECK-NEXT: %1:_ KnownBits:00001010 SignBits:4
- ; CHECK-NEXT: %2:_ KnownBits:0000?01? SignBits:4
- ; CHECK-NEXT: %idx:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1
- ; CHECK-NEXT: %4:_ KnownBits:0000?01? SignBits:4
+ ; CHECK-NEXT: %0:_ KnownBits:00000011 SignBits:6 IsKnownNeverZero:1
+ ; CHECK-NEXT: %1:_ KnownBits:00001010 SignBits:4 IsKnownNeverZero:1
+ ; CHECK-NEXT: %2:_ KnownBits:0000?01? SignBits:4 IsKnownNeverZero:1
+ ; CHECK-NEXT: %idx:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %4:_ KnownBits:0000?01? SignBits:4 IsKnownNeverZero:1
%0:_(i8) = G_CONSTANT i8 3
%1:_(i8) = G_CONSTANT i8 10
%2:_(<2 x i8>) = G_BUILD_VECTOR %0, %1
@@ -38,9 +38,9 @@ name: no_knownbits_const_idx
body: |
bb.0:
; CHECK-LABEL: name: @no_knownbits_const_idx
- ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
- ; CHECK-NEXT: %idx:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000001 SignBits:63
- ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1
+ ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %idx:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000001 SignBits:63 IsKnownNeverZero:1
+ ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
%0:_(<2 x i8>) = COPY $h0
%idx:_(i64) = G_CONSTANT i64 1
%1:_(i8) = G_EXTRACT_VECTOR_ELT %0, %idx
@@ -50,9 +50,9 @@ name: no_knownbits
body: |
bb.0:
; CHECK-LABEL: name: @no_knownbits
- ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
- ; CHECK-NEXT: %idx:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1
- ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1
+ ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %idx:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
%0:_(<2 x i8>) = COPY $h0
%idx:_(i64) = COPY $d1
%1:_(i8) = G_EXTRACT_VECTOR_ELT %0, %idx
@@ -62,10 +62,10 @@ name: zext_const_idx
body: |
bb.0:
; CHECK-LABEL: name: @zext_const_idx
- ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
- ; CHECK-NEXT: %zext0:_ KnownBits:00000000???????? SignBits:8
- ; CHECK-NEXT: %idx:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000001 SignBits:63
- ; CHECK-NEXT: %3:_ KnownBits:00000000???????? SignBits:8
+ ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %zext0:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
+ ; CHECK-NEXT: %idx:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000001 SignBits:63 IsKnownNeverZero:1
+ ; CHECK-NEXT: %3:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
%0:_(<2 x i8>) = COPY $h0
%zext0:_(<2 x i16>) = G_ZEXT %0
%idx:_(i64) = G_CONSTANT i64 1
@@ -77,10 +77,10 @@ body: |
bb.0:
; CHECK-LABEL: name: @zext
- ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
- ; CHECK-NEXT: %zext0:_ KnownBits:00000000???????? SignBits:8
- ; CHECK-NEXT: %idx:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1
- ; CHECK-NEXT: %3:_ KnownBits:00000000???????? SignBits:8
+ ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %zext0:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
+ ; CHECK-NEXT: %idx:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %3:_ KnownBits:00000000???????? SignBits:8 IsKnownNeverZero:0
%0:_(<2 x i8>) = COPY $h0
%zext0:_(<2 x i16>) = G_ZEXT %0
%idx:_(i64) = COPY $d1
@@ -91,10 +91,10 @@ name: sext_const_idx
body: |
bb.0:
; CHECK-LABEL: name: @sext_const_idx
- ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
- ; CHECK-NEXT: %sext0:_ KnownBits:???????????????? SignBits:9
- ; CHECK-NEXT: %idx:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000001 SignBits:63
- ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:1
+ ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %sext0:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+ ; CHECK-NEXT: %idx:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000001 SignBits:63 IsKnownNeverZero:1
+ ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
%0:_(<2 x i8>) = COPY $h0
%sext0:_(<2 x i16>) = G_SEXT %0
%idx:_(i64) = G_CONSTANT i64 1
@@ -105,10 +105,10 @@ name: sext
body: |
bb.0:
; CHECK-LABEL: name: @sext
- ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
- ; CHECK-NEXT: %sext0:_ KnownBits:???????????????? SignBits:9
- ; CHECK-NEXT: %idx:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1
- ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:1
+ ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %sext0:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+ ; CHECK-NEXT: %idx:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
%0:_(<2 x i8>) = COPY $h0
%sext0:_(<2 x i16>) = G_SEXT %0
%idx:_(i64) = COPY $d1
@@ -121,13 +121,44 @@ name: bail_on_different_return_type
body: |
bb.0:
; CHECK-LABEL: name: @bail_on_different_return_type
- ; CHECK-NEXT: %0:_ KnownBits:00000011 SignBits:6
- ; CHECK-NEXT: %1:_ KnownBits:00001010 SignBits:4
- ; CHECK-NEXT: %2:_ KnownBits:0000?01? SignBits:4
- ; CHECK-NEXT: %idx:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000001 SignBits:63
- ; CHECK-NEXT: %4:_ KnownBits:???????????????? SignBits:1
+ ; CHECK-NEXT: %0:_ KnownBits:00000011 SignBits:6 IsKnownNeverZero:1
+ ; CHECK-NEXT: %1:_ KnownBits:00001010 SignBits:4 IsKnownNeverZero:1
+ ; CHECK-NEXT: %2:_ KnownBits:0000?01? SignBits:4 IsKnownNeverZero:1
+ ; CHECK-NEXT: %idx:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000001 SignBits:63 IsKnownNeverZero:1
+ ; CHECK-NEXT: %4:_ KnownBits:???????????????? SignBits:4 IsKnownNeverZero:1
%0:_(i8) = G_CONSTANT i8 3
%1:_(i8) = G_CONSTANT i8 10
%2:_(<2 x i8>) = G_BUILD_VECTOR %0, %1
%idx:_(i64) = G_CONSTANT i64 1
%3:_(i16) = G_EXTRACT_VECTOR_ELT %2, %idx
+---
+# computeNumSignBits: sign bits propagate through G_EXTRACT_VECTOR_ELT
+name: signbits_known_idx
+body: |
+ bb.0:
+ %0:_(i8) = COPY $b0
+ %1:_(i16) = G_SEXT %0
+ %2:_(i16) = COPY $h1
+ %3:_(<4 x i16>) = G_BUILD_VECTOR %1, %1, %2, %1
+ %4:_(i64) = G_CONSTANT i64 0
+ %5:_(i16) = G_EXTRACT_VECTOR_ELT %3, %4
+ %6:_(i64) = G_CONSTANT i64 2
+ %7:_(i16) = G_EXTRACT_VECTOR_ELT %3, %6
+...
+---
+# computeNumSignBits: unknown index demands all elements
+name: signbits_unknown_idx
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @signbits_unknown_idx
+ ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %1:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+ ; CHECK-NEXT: %2:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+ ; CHECK-NEXT: %3:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 IsKnownNeverZero:0
+ ; CHECK-NEXT: %4:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+ %0:_(i8) = COPY $b0
+ %1:_(i16) = G_SEXT %0
+ %2:_(<4 x i16>) = G_BUILD_VECTOR %1, %1, %1, %1
+ %3:_(i64) = COPY $x0
+ %4:_(i16) = G_EXTRACT_VECTOR_ELT %2, %3
+...
>From 1d59085d41d72af4d27602d984afdd23fa8ea7bb Mon Sep 17 00:00:00 2001
From: deepakshirkem <deepakshirke509 at gmail.com>
Date: Mon, 24 Aug 2026 01:46:56 +0530
Subject: [PATCH 2/2] [AArch64] Update neon-extadd-extract tests for improved
GlobalISel sign-bits
GlobalISel now correctly propagates sign bits through G_EXTRACT_VECTOR_ELT,
allowing it to use smull instead of mul for sign-extended vector extracts.
---
llvm/test/CodeGen/AArch64/neon-extadd-extract.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/AArch64/neon-extadd-extract.ll b/llvm/test/CodeGen/AArch64/neon-extadd-extract.ll
index b35511dd4ab69..ae21d8f339dd3 100644
--- a/llvm/test/CodeGen/AArch64/neon-extadd-extract.ll
+++ b/llvm/test/CodeGen/AArch64/neon-extadd-extract.ll
@@ -683,7 +683,7 @@ define <1 x i64> @mulls_v2i32_0(<2 x i32> %s0, <2 x i32> %s1) {
; CHECK-GI-NEXT: sshll v1.2d, v1.2s, #0
; CHECK-GI-NEXT: fmov x8, d0
; CHECK-GI-NEXT: fmov x9, d1
-; CHECK-GI-NEXT: mul x8, x8, x9
+; CHECK-GI-NEXT: smull x8, w8, w9
; CHECK-GI-NEXT: fmov d0, x8
; CHECK-GI-NEXT: ret
entry:
More information about the llvm-commits
mailing list