[llvm] [GlobalISel] Add G_ABS computeKnownBits, add ComputeKnownBitsCache assertion to computeNumSignBits (PR #154413)
Pragyansh Chaturvedi via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 3 00:58:52 PDT 2025
https://github.com/r41k0u updated https://github.com/llvm/llvm-project/pull/154413
>From d98e7359b35eede1f21f5dad48b021568b286e15 Mon Sep 17 00:00:00 2001
From: Pragyansh Chaturvedi <pragyansh.chaturvedi at canonical.com>
Date: Wed, 20 Aug 2025 00:45:25 +0530
Subject: [PATCH 1/7] [GlobalISel] Add G_ABS computeKnownBits
---
.../CodeGen/GlobalISel/GISelValueTracking.cpp | 8 +++++++
.../AArch64/GlobalISel/knownbits-abs.mir | 23 +++++++++++++++++++
2 files changed, 31 insertions(+)
create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abs.mir
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 974fc40de6222..df1b325fa5baf 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -697,6 +697,14 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
}
break;
}
+ case TargetOpcode::G_ABS: {
+ Register SrcReg = MI.getOperand(1).getReg();
+ computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1);
+ Known = Known.abs();
+ Known.Zero.setHighBits(computeNumSignBits(SrcReg, DemandedElts, Depth + 1) -
+ 1);
+ break;
+ }
}
LLVM_DEBUG(dumpResult(MI, Known, Depth));
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abs.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abs.mir
new file mode 100644
index 0000000000000..c3675dc17e342
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abs.mir
@@ -0,0 +1,23 @@
+# 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>" %s -filetype=null 2>&1 | FileCheck %s
+
+---
+name: Cst
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @Cst
+ ; CHECK-NEXT: %0:_ KnownBits:00010011 SignBits:3
+ ; CHECK-NEXT: %1:_ KnownBits:00010011 SignBits:3
+ %0:_(s8) = G_CONSTANT i8 19
+ %1:_(s8) = G_ABS %0
+...
+---
+name: CstNeg
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @CstNeg
+ ; CHECK-NEXT: %0:_ KnownBits:11101110 SignBits:3
+ ; CHECK-NEXT: %1:_ KnownBits:00010010 SignBits:3
+ %0:_(s8) = G_CONSTANT i8 238
+ %1:_(s8) = G_ABS %0
+...
>From 12ec0e5c0b2b8af166f4510ac615b80195a61256 Mon Sep 17 00:00:00 2001
From: Pragyansh Chaturvedi <pragyansh.chaturvedi at canonical.com>
Date: Mon, 1 Sep 2025 02:55:42 +0530
Subject: [PATCH 2/7] [GlobalISel] Add more tests for G_ABS computeKnownBits
---
.../AArch64/GlobalISel/knownbits-abs.mir | 38 ++++++++++++++++++-
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abs.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abs.mir
index c3675dc17e342..1dd67bf301a32 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abs.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abs.mir
@@ -1,5 +1,5 @@
# 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>" %s -filetype=null 2>&1 | FileCheck %s
+# RUN: llc -mtriple=aarch64 -passes='print<gisel-value-tracking>' -filetype=null %s 2>&1 | FileCheck %s
---
name: Cst
@@ -21,3 +21,39 @@ body: |
%0:_(s8) = G_CONSTANT i8 238
%1:_(s8) = G_ABS %0
...
+---
+name: SplatVecCst
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @SplatVecCst
+ ; CHECK-NEXT: %0:_ KnownBits:11111010 SignBits:5
+ ; CHECK-NEXT: %1:_ KnownBits:11111010 SignBits:5
+ ; CHECK-NEXT: %2:_ KnownBits:00000110 SignBits:5
+ %0:_(s8) = G_CONSTANT i8 250
+ %1:_(<vscale x 16 x s8>) = G_SPLAT_VECTOR %0(s8)
+ %2:_(<vscale x 16 x s8>) = G_ABS %1
+...
+---
+name: VecCst
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @VecCst
+ ; CHECK-NEXT: %0:_ KnownBits:00011001 SignBits:3
+ ; CHECK-NEXT: %1:_ KnownBits:11100001 SignBits:3
+ ; CHECK-NEXT: %2:_ KnownBits:?????001 SignBits:3
+ ; CHECK-NEXT: %3:_ KnownBits:0??????1 SignBits:1
+ %0:_(s8) = G_CONSTANT i8 25
+ %1:_(s8) = G_CONSTANT i8 225
+ %2:_(<2 x s8>) = G_BUILD_VECTOR %0:_(s8), %1:_(s8)
+ %3:_(<2 x s8>) = G_ABS %2
+...
+---
+name: ImplicitDef
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @ImplicitDef
+ ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+ ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1
+ %0:_(s8) = G_IMPLICIT_DEF
+ %1:_(s8) = G_ABS %0
+...
>From fbf33dd26139b6b7bd2af16e3fbc827f54022891 Mon Sep 17 00:00:00 2001
From: Pragyansh Chaturvedi <pragyansh.chaturvedi at canonical.com>
Date: Mon, 1 Sep 2025 15:44:54 +0530
Subject: [PATCH 3/7] [GlobalISel] Add cache assertion and clearing to
GISelValueTracking::computeNumSignBits
---
llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index df1b325fa5baf..b503abc793271 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -2045,7 +2045,8 @@ unsigned GISelValueTracking::computeNumSignBits(Register R,
// Finally, if we can prove that the top bits of the result are 0's or 1's,
// use this information.
- KnownBits Known = getKnownBits(R, DemandedElts, Depth);
+ KnownBits Known;
+ computeKnownBitsImpl(R, Known, DemandedElts, Depth + 1);
APInt Mask;
if (Known.isNonNegative()) { // sign bit is 0
Mask = Known.Zero;
@@ -2066,7 +2067,10 @@ unsigned GISelValueTracking::computeNumSignBits(Register R, unsigned Depth) {
LLT Ty = MRI.getType(R);
APInt DemandedElts =
Ty.isFixedVector() ? APInt::getAllOnes(Ty.getNumElements()) : APInt(1, 1);
- return computeNumSignBits(R, DemandedElts, Depth);
+ assert(ComputeKnownBitsCache.empty() && "Cache should be empty");
+ unsigned numSignBits = computeNumSignBits(R, DemandedElts, Depth);
+ ComputeKnownBitsCache.clear();
+ return numSignBits;
}
std::optional<ConstantRange> GISelValueTracking::getValidShiftAmountRange(
@@ -2172,7 +2176,7 @@ GISelValueTrackingPrinterPass::run(MachineFunction &MF,
Register Reg = MO.getReg();
if (!MRI.getType(Reg).isValid())
continue;
- KnownBits Known = VTA.getKnownBits(Reg);
+ KnownBits Known = VTA.getKnownBits(Reg);
unsigned SignedBits = VTA.computeNumSignBits(Reg);
OS << " " << MO << " KnownBits:" << Known << " SignBits:" << SignedBits
<< '\n';
>From d8ca38464f857ff6db49b73baed71ca1ca83a4ba Mon Sep 17 00:00:00 2001
From: Pragyansh Chaturvedi <pragyansh.chaturvedi at canonical.com>
Date: Mon, 1 Sep 2025 15:49:12 +0530
Subject: [PATCH 4/7] [GlobalISel] Add sign extension tests for knownbits_abs,
update tests
---
.../AArch64/GlobalISel/knownbits-abs.mir | 26 ++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abs.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abs.mir
index 1dd67bf301a32..b4ac62cd992cf 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abs.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abs.mir
@@ -41,7 +41,7 @@ body: |
; CHECK-NEXT: %0:_ KnownBits:00011001 SignBits:3
; CHECK-NEXT: %1:_ KnownBits:11100001 SignBits:3
; CHECK-NEXT: %2:_ KnownBits:?????001 SignBits:3
- ; CHECK-NEXT: %3:_ KnownBits:0??????1 SignBits:1
+ ; CHECK-NEXT: %3:_ KnownBits:00?????1 SignBits:2
%0:_(s8) = G_CONSTANT i8 25
%1:_(s8) = G_CONSTANT i8 225
%2:_(<2 x s8>) = G_BUILD_VECTOR %0:_(s8), %1:_(s8)
@@ -57,3 +57,27 @@ body: |
%0:_(s8) = G_IMPLICIT_DEF
%1:_(s8) = G_ABS %0
...
+---
+name: CstSext
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @CstSext
+ ; CHECK-NEXT: %0:_ KnownBits:11000111 SignBits:2
+ ; CHECK-NEXT: %1:_ KnownBits:1111111111000111 SignBits:10
+ ; CHECK-NEXT: %2:_ KnownBits:0000000000111001 SignBits:10
+ %0:_(s8) = G_CONSTANT i8 199
+ %1:_(s16) = G_SEXT %0
+ %2:_(s16) = G_ABS %1
+...
+---
+name: ImplicitDefSext
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @ImplicitDefSext
+ ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+ ; CHECK-NEXT: %1:_ KnownBits:???????????????? SignBits:9
+ ; CHECK-NEXT: %2:_ KnownBits:00000000???????? SignBits:8
+ %0:_(s8) = G_IMPLICIT_DEF
+ %1:_(s16) = G_SEXT %0
+ %2:_(s16) = G_ABS %1
+...
>From 907deebb9dbe41bda985d670bd6bf6f2d07a92e6 Mon Sep 17 00:00:00 2001
From: Pragyansh Chaturvedi <pragyansh.chaturvedi at canonical.com>
Date: Mon, 1 Sep 2025 15:52:47 +0530
Subject: [PATCH 5/7] [GlobalISel] Fix formatting in
GISelValueTrackingPrinterPass::run
---
llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index b503abc793271..df34fda47eed8 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -2176,7 +2176,7 @@ GISelValueTrackingPrinterPass::run(MachineFunction &MF,
Register Reg = MO.getReg();
if (!MRI.getType(Reg).isValid())
continue;
- KnownBits Known = VTA.getKnownBits(Reg);
+ KnownBits Known = VTA.getKnownBits(Reg);
unsigned SignedBits = VTA.computeNumSignBits(Reg);
OS << " " << MO << " KnownBits:" << Known << " SignBits:" << SignedBits
<< '\n';
>From 0e4af4b314fbcdd7cf5325cb6d9e36cb82eef53f Mon Sep 17 00:00:00 2001
From: Pragyansh Chaturvedi <pragyansh.chaturvedi at canonical.com>
Date: Wed, 3 Sep 2025 12:18:05 +0530
Subject: [PATCH 6/7] [GlobalIsel] Add computeNumSignBitsImpl to
GISelValueTracking
---
.../llvm/CodeGen/GlobalISel/GISelValueTracking.h | 4 ++++
.../CodeGen/GlobalISel/GISelValueTracking.cpp | 16 +++++++++++-----
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GISelValueTracking.h b/llvm/include/llvm/CodeGen/GlobalISel/GISelValueTracking.h
index 490d1a34cc846..01898cd853714 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GISelValueTracking.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GISelValueTracking.h
@@ -70,6 +70,10 @@ class LLVM_ABI GISelValueTracking : public GISelChangeObserver {
const APInt &DemandedElts,
unsigned Depth = 0);
+ virtual unsigned computeNumSignBitsImpl(Register R,
+ const APInt &DemandedElts,
+ unsigned Depth = 0);
+
unsigned computeNumSignBits(Register R, const APInt &DemandedElts,
unsigned Depth = 0);
unsigned computeNumSignBits(Register R, unsigned Depth = 0);
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index df34fda47eed8..19eb0e591e070 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -1789,7 +1789,7 @@ static unsigned computeNumSignBitsFromRangeMetadata(const GAnyLoad *Ld,
CR.getSignedMax().getNumSignBits());
}
-unsigned GISelValueTracking::computeNumSignBits(Register R,
+unsigned GISelValueTracking::computeNumSignBitsImpl(Register R,
const APInt &DemandedElts,
unsigned Depth) {
MachineInstr &MI = *MRI.getVRegDef(R);
@@ -2063,14 +2063,20 @@ unsigned GISelValueTracking::computeNumSignBits(Register R,
return std::max(FirstAnswer, Mask.countl_one());
}
+unsigned GISelValueTracking::computeNumSignBits(Register R,
+ const APInt &DemandedElts,
+ unsigned Depth) {
+ assert(ComputeKnownBitsCache.empty() && "Cache should be empty");
+ unsigned NumSignBits = computeNumSignBitsImpl(R, DemandedElts, Depth);
+ ComputeKnownBitsCache.clear();
+ return NumSignBits;
+}
+
unsigned GISelValueTracking::computeNumSignBits(Register R, unsigned Depth) {
LLT Ty = MRI.getType(R);
APInt DemandedElts =
Ty.isFixedVector() ? APInt::getAllOnes(Ty.getNumElements()) : APInt(1, 1);
- assert(ComputeKnownBitsCache.empty() && "Cache should be empty");
- unsigned numSignBits = computeNumSignBits(R, DemandedElts, Depth);
- ComputeKnownBitsCache.clear();
- return numSignBits;
+ return computeNumSignBits(R, DemandedElts, Depth);
}
std::optional<ConstantRange> GISelValueTracking::getValidShiftAmountRange(
>From d930634501f41c745c97af0b84569afa6a80b585 Mon Sep 17 00:00:00 2001
From: Pragyansh Chaturvedi <pragyansh.chaturvedi at canonical.com>
Date: Wed, 3 Sep 2025 13:28:09 +0530
Subject: [PATCH 7/7] [GlobalISel] Update aarch64-smull.ll test
---
llvm/test/CodeGen/AArch64/aarch64-smull.ll | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/llvm/test/CodeGen/AArch64/aarch64-smull.ll b/llvm/test/CodeGen/AArch64/aarch64-smull.ll
index 6e5c666bdbc75..52cb13b1d9f30 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-smull.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-smull.ll
@@ -249,10 +249,20 @@ define <2 x i64> @smull_zext_v2i32_v2i64(ptr %A, ptr %B) nounwind {
; CHECK-GI-NEXT: movi d0, #0x00ffff0000ffff
; CHECK-GI-NEXT: mov v1.s[1], v2.s[0]
; CHECK-GI-NEXT: and v0.8b, v1.8b, v0.8b
-; CHECK-GI-NEXT: mov v1.s[0], v0.s[0]
-; CHECK-GI-NEXT: mov v1.s[1], v0.s[1]
+; CHECK-GI-NEXT: mov w8, v0.s[0]
+; CHECK-GI-NEXT: mov w9, v0.s[1]
; CHECK-GI-NEXT: ldr d0, [x1]
-; CHECK-GI-NEXT: smull v0.2d, v1.2s, v0.2s
+; CHECK-GI-NEXT: sshll v0.2d, v0.2s, #0
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: fmov x11, d0
+; CHECK-GI-NEXT: mov v1.d[1], x9
+; CHECK-GI-NEXT: mov x9, v0.d[1]
+; CHECK-GI-NEXT: fmov x10, d1
+; CHECK-GI-NEXT: mov x8, v1.d[1]
+; CHECK-GI-NEXT: mul x10, x10, x11
+; CHECK-GI-NEXT: mul x8, x8, x9
+; CHECK-GI-NEXT: fmov d0, x10
+; CHECK-GI-NEXT: mov v0.d[1], x8
; CHECK-GI-NEXT: ret
%load.A = load <2 x i16>, ptr %A
%load.B = load <2 x i32>, ptr %B
More information about the llvm-commits
mailing list