[llvm] [GlobalISel] add KnownBits tracking for G_UMULH and G_SMULH (PR #158445)

Pragyansh Chaturvedi via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 14 14:24:05 PDT 2025


https://github.com/r41k0u updated https://github.com/llvm/llvm-project/pull/158445

>From 3574456e98da8b83b2da95e5cbac49d3c3e915ee Mon Sep 17 00:00:00 2001
From: Pragyansh Chaturvedi <pragyanshchaturvedi18 at gmail.com>
Date: Sat, 13 Sep 2025 22:04:51 +0000
Subject: [PATCH 1/3] [GlobalISel] add KnownBits tracking for G_UMULH and
 G_SMULH

---
 .../CodeGen/GlobalISel/GISelValueTracking.cpp    | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 0cf44e02254de..1b8d192e53fcd 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -366,6 +366,22 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
     Known = KnownBits::mul(Known, Known2);
     break;
   }
+  case TargetOpcode::G_UMULH: {
+    computeKnownBitsImpl(MI.getOperand(2).getReg(), Known, DemandedElts,
+                         Depth + 1);
+    computeKnownBitsImpl(MI.getOperand(1).getReg(), Known2, DemandedElts,
+                         Depth + 1);
+    Known = KnownBits::mulhu(Known, Known2);
+    break;
+  }
+  case TargetOpcode::G_SMULH: {
+    computeKnownBitsImpl(MI.getOperand(2).getReg(), Known, DemandedElts,
+                         Depth + 1);
+    computeKnownBitsImpl(MI.getOperand(1).getReg(), Known2, DemandedElts,
+                         Depth + 1);
+    Known = KnownBits::mulhs(Known, Known2);
+    break;
+  }
   case TargetOpcode::G_SELECT: {
     computeKnownBitsMin(MI.getOperand(2).getReg(), MI.getOperand(3).getReg(),
                         Known, DemandedElts, Depth + 1);

>From 468f4e48dc203f836cba188889ee7b214d3d4023 Mon Sep 17 00:00:00 2001
From: Pragyansh Chaturvedi <pragyanshchaturvedi18 at gmail.com>
Date: Sun, 14 Sep 2025 20:59:09 +0000
Subject: [PATCH 2/3] [GlobalISel] add GISelValueTracking tests for G_UMULH and
 G_SMULH

---
 .../AArch64/GlobalISel/knownbits-smulh.mir    | 137 ++++++++++++++++++
 .../AArch64/GlobalISel/knownbits-umulh.mir    | 137 ++++++++++++++++++
 2 files changed, 274 insertions(+)
 create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/knownbits-smulh.mir
 create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/knownbits-umulh.mir

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-smulh.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-smulh.mir
new file mode 100644
index 0000000000000..b9cde9587c78c
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-smulh.mir
@@ -0,0 +1,137 @@
+# 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>' -filetype=null %s 2>&1 | FileCheck %s
+
+---
+name: Cst
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @Cst
+  ; CHECK-NEXT: %0:_ KnownBits:00010011 SignBits:3
+  ; CHECK-NEXT: %1:_ KnownBits:11100000 SignBits:3
+  ; CHECK-NEXT: %2:_ KnownBits:11111101 SignBits:6
+    %0:_(s8) = G_CONSTANT i8 19
+    %1:_(s8) = G_CONSTANT i8 224
+    %2:_(s8) = G_SMULH %0, %1
+...
+---
+name: CstZero
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @CstZero
+  ; CHECK-NEXT: %0:_ KnownBits:11111111 SignBits:8
+  ; CHECK-NEXT: %1:_ KnownBits:00000000 SignBits:8
+  ; CHECK-NEXT: %2:_ KnownBits:00000000 SignBits:8
+    %0:_(s8) = G_CONSTANT i8 255
+    %1:_(s8) = G_CONSTANT i8 0
+    %2:_(s8) = G_SMULH %0, %1
+...
+---
+name: ScalarVar
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @ScalarVar
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1
+    %0:_(s8) = COPY $b0
+    %1:_(s8) = COPY $b1
+    %2:_(s8) = G_SMULH %0, %1
+...
+---
+name: ScalarZero
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @ScalarZero
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:00000000 SignBits:8
+  ; CHECK-NEXT: %2:_ KnownBits:00000000 SignBits:8
+    %0:_(s8) = COPY $b0
+    %1:_(s8) = G_CONSTANT i8 0
+    %2:_(s8) = G_SMULH %0, %1
+...
+---
+name: ScalarVarAbs
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @ScalarVarAbs
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????? SignBits:9
+  ; CHECK-NEXT: %3:_ KnownBits:0000000000000001 SignBits:15
+  ; CHECK-NEXT: %4:_ KnownBits:???????????????? SignBits:1
+    %0:_(s8) = COPY $b0
+    %1:_(s8) = G_ABS %0
+    %2:_(s16) = G_SEXT %1
+    %3:_(s16) = G_CONSTANT i16 1
+    %4:_(s16) = G_SMULH %2, %3
+...
+---
+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:11111010 SignBits:5
+  ; CHECK-NEXT: %3:_ KnownBits:00000000 SignBits:8
+    %0:_(s8) = G_CONSTANT i8 250
+    %1:_(<vscale x 16 x s8>) = G_SPLAT_VECTOR %0(s8)
+    %2:_(<vscale x 16 x s8>) = G_SPLAT_VECTOR %0(s8)
+    %3:_(<vscale x 16 x s8>) = G_SMULH %1, %2
+...
+---
+name: SplatVecPartScalar
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @SplatVecPartScalar
+  ; CHECK-NEXT: %0:_ KnownBits:11111010 SignBits:5
+  ; CHECK-NEXT: %1:_ KnownBits:11111010 SignBits:5
+  ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %3:_ KnownBits:00001111 SignBits:4
+  ; CHECK-NEXT: %4:_ KnownBits:0000???? SignBits:4
+  ; CHECK-NEXT: %5:_ KnownBits:0000???? SignBits:4
+  ; CHECK-NEXT: %6:_ KnownBits:???????? SignBits:1
+    %0:_(s8) = G_CONSTANT i8 250
+    %1:_(<vscale x 16 x s8>) = G_SPLAT_VECTOR %0(s8)
+    %2:_(s8) = G_IMPLICIT_DEF
+    %3:_(s8) = G_CONSTANT i8 15
+    %4:_(s8) = G_AND %2, %3
+    %5:_(<vscale x 16 x s8>) = G_SPLAT_VECTOR %4(s8)
+    %6:_(<vscale x 16 x s8>) = G_SMULH %1, %5
+...
+---
+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:?????001 SignBits:3
+  ; CHECK-NEXT: %4:_ KnownBits:???????? 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_BUILD_VECTOR %0:_(s8), %1:_(s8)
+    %4:_(<2 x s8>) = G_SMULH %2, %3
+...
+---
+name: VecPartScalar
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @VecPartScalar
+  ; CHECK-NEXT: %0:_ KnownBits:11111010 SignBits:5
+  ; CHECK-NEXT: %1:_ KnownBits:11111010 SignBits:5
+  ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %3:_ KnownBits:00001111 SignBits:4
+  ; CHECK-NEXT: %4:_ KnownBits:0000???? SignBits:4
+  ; CHECK-NEXT: %5:_ KnownBits:0000???? SignBits:4
+  ; CHECK-NEXT: %6:_ KnownBits:???????? SignBits:1
+    %0:_(s8) = G_CONSTANT i8 250
+    %1:_(<2 x s8>) = G_BUILD_VECTOR %0:_(s8), %0:_(s8)
+    %2:_(s8) = G_IMPLICIT_DEF
+    %3:_(s8) = G_CONSTANT i8 15
+    %4:_(s8) = G_AND %2, %3
+    %5:_(<2 x s8>) = G_BUILD_VECTOR %4:_(s8), %4:_(s8)
+    %6:_(<2 x s8>) = G_SMULH %1, %5
+...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-umulh.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-umulh.mir
new file mode 100644
index 0000000000000..debdbaaeecf5c
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-umulh.mir
@@ -0,0 +1,137 @@
+# 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>' -filetype=null %s 2>&1 | FileCheck %s
+
+---
+name: Cst
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @Cst
+  ; CHECK-NEXT: %0:_ KnownBits:00010011 SignBits:3
+  ; CHECK-NEXT: %1:_ KnownBits:11100000 SignBits:3
+  ; CHECK-NEXT: %2:_ KnownBits:00010000 SignBits:3
+    %0:_(s8) = G_CONSTANT i8 19
+    %1:_(s8) = G_CONSTANT i8 224
+    %2:_(s8) = G_UMULH %0, %1
+...
+---
+name: CstZero
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @CstZero
+  ; CHECK-NEXT: %0:_ KnownBits:11111111 SignBits:8
+  ; CHECK-NEXT: %1:_ KnownBits:00000000 SignBits:8
+  ; CHECK-NEXT: %2:_ KnownBits:00000000 SignBits:8
+    %0:_(s8) = G_CONSTANT i8 255
+    %1:_(s8) = G_CONSTANT i8 0
+    %2:_(s8) = G_UMULH %0, %1
+...
+---
+name: ScalarVar
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @ScalarVar
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1
+    %0:_(s8) = COPY $b0
+    %1:_(s8) = COPY $b1
+    %2:_(s8) = G_UMULH %0, %1
+...
+---
+name: ScalarZero
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @ScalarZero
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:00000000 SignBits:8
+  ; CHECK-NEXT: %2:_ KnownBits:00000000 SignBits:8
+    %0:_(s8) = COPY $b0
+    %1:_(s8) = G_CONSTANT i8 0
+    %2:_(s8) = G_UMULH %0, %1
+...
+---
+name: ScalarVarAbs
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @ScalarVarAbs
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????? SignBits:9
+  ; CHECK-NEXT: %3:_ KnownBits:0000000000000001 SignBits:15
+  ; CHECK-NEXT: %4:_ KnownBits:0000000000000000 SignBits:16
+    %0:_(s8) = COPY $b0
+    %1:_(s8) = G_ABS %0
+    %2:_(s16) = G_SEXT %1
+    %3:_(s16) = G_CONSTANT i16 1
+    %4:_(s16) = G_UMULH %2, %3
+...
+---
+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:11111010 SignBits:5
+  ; CHECK-NEXT: %3:_ KnownBits:11110100 SignBits:4
+    %0:_(s8) = G_CONSTANT i8 250
+    %1:_(<vscale x 16 x s8>) = G_SPLAT_VECTOR %0(s8)
+    %2:_(<vscale x 16 x s8>) = G_SPLAT_VECTOR %0(s8)
+    %3:_(<vscale x 16 x s8>) = G_UMULH %1, %2
+...
+---
+name: SplatVecPartScalar
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @SplatVecPartScalar
+  ; CHECK-NEXT: %0:_ KnownBits:11111010 SignBits:5
+  ; CHECK-NEXT: %1:_ KnownBits:11111010 SignBits:5
+  ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %3:_ KnownBits:00001111 SignBits:4
+  ; CHECK-NEXT: %4:_ KnownBits:0000???? SignBits:4
+  ; CHECK-NEXT: %5:_ KnownBits:0000???? SignBits:4
+  ; CHECK-NEXT: %6:_ KnownBits:0000???? SignBits:4
+    %0:_(s8) = G_CONSTANT i8 250
+    %1:_(<vscale x 16 x s8>) = G_SPLAT_VECTOR %0(s8)
+    %2:_(s8) = G_IMPLICIT_DEF
+    %3:_(s8) = G_CONSTANT i8 15
+    %4:_(s8) = G_AND %2, %3
+    %5:_(<vscale x 16 x s8>) = G_SPLAT_VECTOR %4(s8)
+    %6:_(<vscale x 16 x s8>) = G_UMULH %1, %5
+...
+---
+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:?????001 SignBits:3
+  ; CHECK-NEXT: %4:_ KnownBits:???????? 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_BUILD_VECTOR %0:_(s8), %1:_(s8)
+    %4:_(<2 x s8>) = G_UMULH %2, %3
+...
+---
+name: VecPartScalar
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @VecPartScalar
+  ; CHECK-NEXT: %0:_ KnownBits:11111010 SignBits:5
+  ; CHECK-NEXT: %1:_ KnownBits:11111010 SignBits:5
+  ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %3:_ KnownBits:00001111 SignBits:4
+  ; CHECK-NEXT: %4:_ KnownBits:0000???? SignBits:4
+  ; CHECK-NEXT: %5:_ KnownBits:0000???? SignBits:4
+  ; CHECK-NEXT: %6:_ KnownBits:0000???? SignBits:4
+    %0:_(s8) = G_CONSTANT i8 250
+    %1:_(<2 x s8>) = G_BUILD_VECTOR %0:_(s8), %0:_(s8)
+    %2:_(s8) = G_IMPLICIT_DEF
+    %3:_(s8) = G_CONSTANT i8 15
+    %4:_(s8) = G_AND %2, %3
+    %5:_(<2 x s8>) = G_BUILD_VECTOR %4:_(s8), %4:_(s8)
+    %6:_(<2 x s8>) = G_UMULH %1, %5
+...

>From 27526494f9ab2b4e7a7b4b44ad85c2b6cd2e0143 Mon Sep 17 00:00:00 2001
From: Pragyansh Chaturvedi <pragyanshchaturvedi18 at gmail.com>
Date: Sun, 14 Sep 2025 21:22:37 +0000
Subject: [PATCH 3/3] [GlobalISel] update CodeGen/AArch64/pr58431.ll to agree
 with KnownBits changes

---
 llvm/test/CodeGen/AArch64/pr58431.ll | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/AArch64/pr58431.ll b/llvm/test/CodeGen/AArch64/pr58431.ll
index 467ceb062f249..a37300432bca0 100644
--- a/llvm/test/CodeGen/AArch64/pr58431.ll
+++ b/llvm/test/CodeGen/AArch64/pr58431.ll
@@ -9,7 +9,7 @@ define i32 @f(i64 %0) {
 ; CHECK-NEXT:    mov w10, #10 // =0xa
 ; CHECK-NEXT:    eor x8, x8, #0x8000000000000003
 ; CHECK-NEXT:    umulh x8, x9, x8
-; CHECK-NEXT:    msub x0, x8, x10, x9
+; CHECK-NEXT:    umsubl x0, w8, w10, x9
 ; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
 ; CHECK-NEXT:    ret
   %2 = trunc i64 %0 to i32



More information about the llvm-commits mailing list