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

via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 14 14:05:51 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Pragyansh Chaturvedi (r41k0u)

<details>
<summary>Changes</summary>

The code is taken from `SelectionDAG::computeKnownBits`.
This ticks off `MULHU` and `MULHS` from https://github.com/llvm/llvm-project/issues/150515

---
Full diff: https://github.com/llvm/llvm-project/pull/158445.diff


3 Files Affected:

- (modified) llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp (+16) 
- (added) llvm/test/CodeGen/AArch64/GlobalISel/knownbits-smulh.mir (+137) 
- (added) llvm/test/CodeGen/AArch64/GlobalISel/knownbits-umulh.mir (+137) 


``````````diff
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);
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
+...

``````````

</details>


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


More information about the llvm-commits mailing list